/*
 * This file is part of algowala.
 *
 * algowala is copyright (c) 2012 Jagannathan Sampath <algowala@jagernot.com>
 *
 * algowala is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * algowala is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with algowala.  If not, see <http://www.gnu.org/licenses/>.
 *
*/
#include "chrono.h"
#include "tokenizer.h"

#include <iostream>
using namespace std;

using namespace boost::gregorian;
using namespace boost::posix_time;


chrono::chrono (double _time_scale) {
  set_time_scale (_time_scale);
  reset ();
}

void chrono::reset () {
  start = microsec_clock::local_time ();
  elapsed = seconds (0);
}

void chrono::tick () {
  now = microsec_clock::local_time ();
  time_duration delta_elapsed (now - start); 
  delta_elapsed *= time_scale;
  double delta_secs = delta_elapsed.total_microseconds () / 1000000.0;
  elapsed += delta_elapsed;
  secs += delta_secs;
  start = now;
}

long chrono::get_seed () {
  now = microsec_clock::local_time ();
  time_duration elapsed (now - start);
  return elapsed.total_microseconds ();
}

string chrono::get_wall_clock () {
  
  tokenizer tz (to_simple_string (market_open + elapsed));
  
  string ignore, wall_clock; 
  tz >> ignore >> wall_clock;
  
  return wall_clock;
  
}

string chrono::get_wall_clock (double s, const ptime& startt) {
  
  double ds = s - (int) s;
  time_duration duration (0, 0, s, ds);
  tokenizer tz (to_simple_string (startt + duration));
  
  string ignore, wall_clock; 
  tz >> ignore >> wall_clock;
  
  return wall_clock;
  
}

chrono1::chrono1 (double _time_scale) {
  time_scale = _time_scale;
  secs = 0;
}

void chrono1::reset () {
  clock_gettime (CLOCK_MONOTONIC, &start);
  secs = 0;
}

void chrono1::tick () {
  clock_gettime (CLOCK_MONOTONIC, &now);
  find_elapsed (start, now, result);
  secs += time_scale * (result.tv_sec + result.tv_nsec / 1000000000.0);
  start = now;
}

void find_elapsed (const timespec& start, const timespec& end, timespec& result)  {
  if (( end.tv_nsec - start.tv_nsec ) < 0) {
    result.tv_sec = end.tv_sec - start.tv_sec - 1;
    result.tv_nsec = end.tv_nsec + 1000000000 - start.tv_nsec;
  } else {
    result.tv_sec = end.tv_sec - start.tv_sec;
    result.tv_nsec = end.tv_nsec - start.tv_nsec;
  }
}



